<template>
  <el-form
    ref="formRef"
    :model="spuInfo"
    :rules="rules"
    label-width="120px"
    action="/xxx"
    @submit.prevent
  >
    <el-form-item label="SPU名称" prop="spuName">
      <el-input placeholder="SPU名称" v-model="spuInfo.spuName"></el-input>
    </el-form-item>
    <el-form-item label="品牌" prop="tmId">
      <el-select v-model="spuInfo.tmId">
        <el-option
          v-for="tm in trademarkList"
          :key="tm.id"
          :label="tm.tmName"
          :value="tm.id || 0"
        ></el-option>
      </el-select>
    </el-form-item>

    <el-form-item label="SPU描述" prop="description">
      <el-input
        type="textarea"
        placeholder="SPU描述"
        rows="4"
        v-model="spuInfo.description"
      ></el-input>
    </el-form-item>

    <el-form-item label="SPU图片" prop="spuImageList">
      <el-upload
        multiple
        :file-list="(spuInfo.spuImageList as any)"
        :action="`${BASE_URL}/admin/product/fileUpload`"
        list-type="picture-card"
        :on-preview="handlePictureCardPreview"
        :on-success="handleSuccess"
        :on-remove="handleRemove"
      >
        <el-icon><Plus /></el-icon>
      </el-upload>
      <el-dialog v-model="dialogVisible">
        <img w-full :src="dialogImageUrl" alt="" />
      </el-dialog>
    </el-form-item>

    <el-form-item label="销售属性" prop="spuSaleAttrList">
      <el-select v-model="saleAttrIdName" :placeholder="saleListText">
        <el-option
          v-for="item in unUseSaleAttrList"
          :key="item.id"
          :label="item.name"
          :value="item.id + ':' + item.name"
        ></el-option>
      </el-select>
      <el-button type="primary" icon="el-icon-plus" @click="addSpuSaleAttr"
        >添加销售属性</el-button
      >
      <el-table style="margin: 20px 0" :data="spuInfo?.spuSaleAttrList" border>
        <el-table-column label="序号" type="index" width="80" align="center">
        </el-table-column>
        <el-table-column label="属性名" prop="saleAttrName" width="150">
        </el-table-column>
        <el-table-column label="属性值名称列表">
          <template v-slot="{ row, $index }">
            <el-tag
              closable
              :disable-transitions="false"
              @close="row.spuSaleAttrValueList.splice(index, 1)"
              style="margin-right: 5px"
              v-for="(item, index) in row.spuSaleAttrValueList"
              :key="item.saleAttrValueName"
              type="success"
              >{{ item.saleAttrValueName }}</el-tag
            >

            <el-input
              v-model="saleAttrValueName"
              v-if="row.isShowEdit"
              @blur="toView(row)"
              :ref="(input: any) => {inputsRef[$index] = input}"
              placeholder="名称"
              size="small"
              style="width: 100px"
            />
            <el-button
              @click="toEdit(row, $index)"
              v-else
              size="small"
              :icon="Plus"
            ></el-button>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="150">
          <template v-slot="{ $index }">
            <el-button
              @click="spuInfo?.spuSaleAttrList.splice($index, 1)"
              title="删除"
              type="danger"
              size="small"
              :icon="Delete"
            ></el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-form-item>

    <el-form-item>
      <el-button type="primary" @click="save">保存</el-button>
      <el-button @click="emits('setShowStatus', ShowStatus.SPU_LIST)"
        >取消</el-button
      >
    </el-form-item>
  </el-form>
</template>

<script lang="ts">
  export default {
    name: "SpuForm",
  };
</script>

<script lang="ts" setup>
  import {
    ElIcon,
    ElForm,
    ElFormItem,
    ElInput,
    ElSelect,
    ElOption,
    ElUpload,
    ElTable,
    ElTableColumn,
    ElTag,
    ElButton,
    ElMessage,
  } from "element-plus";
  import type {
    UploadFile,
    UploadFiles,
    FormRules,
    FormInstance,
  } from "element-plus";
  import { Plus, Delete } from "@element-plus/icons-vue";
  import { computed, nextTick, ref, reactive, onMounted } from "vue";
  import type {
    BaseSaleAttrListModel,
    SpuModel,
    SpuSaleAttrModel,
  } from "@/api/product/model/spuModel";
  import type { TrademarkListModel } from "@/api/product/model/trademarkModel";
  import {
    addOrUpdateSpuApi,
    getSpuImageListApi,
    getBaseSaleAttrListApi,
    getSpuSaleAttrListApi,
  } from "@/api/product/spu";
  import { getAllTrademarkListApi } from "@/api/product/trademark";
  import { ShowStatus } from "../types";
  import { useCategoryStore } from "@/stores/category";

  const categoryStore = useCategoryStore();
  const emits = defineEmits(["setShowStatus"]);
  const props = defineProps<{
    currentSpu: SpuModel;
  }>();

  // 上传图片地址：从.env.development中加载的
  const BASE_URL = import.meta.env.VITE_BASE_URL;

  const dialogImageUrl = ref("");
  const dialogVisible = ref(false);
  const spuInfo = reactive<SpuModel>(props.currentSpu);
  const trademarkList = ref<TrademarkListModel>([]); // 品牌列表
  const baseSaleAttrList = ref<BaseSaleAttrListModel>([]); // 基础销售属性列表
  const saleAttrIdName = ref(""); // 用于收集选择的销售属性   id:name

  const saleAttrValueName = ref<string>(""); // 收集用户输入的销售属性值名称

  const inputsRef = ref<HTMLInputElement[]>([]);
  const formRef = ref<FormInstance>();

  // 表单验证规则
  const rules: FormRules = {
    spuName: [{ required: true, message: "请输入SPU名称", trigger: "blur" }],
    tmId: [{ required: true, message: "请选择SPU品牌" }],
    description: [
      { required: true, message: "请输入SPU描述", trigger: "blur" },
    ],
    spuImageList: [{ required: true, message: "请上传SPU图片", type: "array" }],
    spuSaleAttrList: [
      { required: true, message: "请添加SPU销售属性", type: "array" },
    ],
  };

  // 生命周期可以写多个
  onMounted(async () => {
    // 获取基础销售属性列表
    baseSaleAttrList.value = await getBaseSaleAttrListApi();
  });
  onMounted(async () => {
    // 获取所有品牌列表
    trademarkList.value = await getAllTrademarkListApi();
  });
  onMounted(async () => {
    // 如果spuInfo有id, 获取spu图片列表
    const id = spuInfo.id as number;
    if (!id) return;
    const spuImageList = await getSpuImageListApi(id);

    spuInfo.spuImageList = spuImageList.map((item) => ({
      ...item,
      name: item.imgName,
      url: item.imgUrl,
    }));
  });
  onMounted(async () => {
    // 如果spuInfo有id, 获取spu销售属性列表
    const id = spuInfo.id as number;
    if (!id) return;
    spuInfo.spuSaleAttrList = await getSpuSaleAttrListApi(id);
  });

  /* 
  上传图片成功的回调
  response: 响应体对象
  file: 上传成功的文件对象
  fileList: 所有已上传的文件对象的数组
  */
  const handleSuccess = (
    response: any,
    file: UploadFile,
    fileList: UploadFiles
  ) => {
    // console.log('handleSuccess', fileList)
    spuInfo.spuImageList = fileList as any;
  };

  /* 
  删除图的回调
  file: 删除文件对象
  fileList: 剩下的已上传的文件对象的数组
  */
  const handleRemove = (file: UploadFile, fileList: UploadFiles) => {
    spuInfo.spuImageList = fileList as any;
  };

  /**
   * 点击放大镜图标的回调
   * @param file
   */
  const handlePictureCardPreview = (file: UploadFile) => {
    console.log(file);

    // 保存预览的图片url
    dialogImageUrl.value = file.url as string;
    // 显示dialog
    dialogVisible.value = true;
  };

  /* 
  用于显示下拉列表的未使用的销售属性列表
  */
  const unUseSaleAttrList = computed(() => {
    // 计算产生一个要用的数据, 并返回
    // 过滤总销售属性列表
    return baseSaleAttrList.value.filter((attr) => {
      // 看attr.name有没有在spuSaleAttrList中一个对应的   name===saleAttrName
      // 如果没有, 才留下来
      return !spuInfo.spuSaleAttrList.some(
        (item) => item.saleAttrName == attr.name
      );
      // return spuInfo.value?.spuSaleAttrList.every(item => item.saleAttrName!=attr.name)
    });
  });

  /* 
  销售属性下拉列表的文本提示
  */
  const saleListText = computed(() => {
    const { length } = unUseSaleAttrList.value;
    return length > 0 ? `还有${length}未选择` : "没有啦!";
  });

  /* 
  添加或者更新spuInfo
  */
  const save = async () => {
    // 进行表单校验, 如果通过返回成功的promise
    await formRef.value?.validate();

    // 整理1: spuImageList
    /* 
      从后台获取的图片文件对象的结构
			{
			    "id": 333,
			    "spuId": 26,
			    "imgName": "rBHu8l6UcKyAfzDsAAAPN5YrVxw870.jpg",
			    "imgUrl": "http://47.93.148.192:8080/xxx.jpg",
				 "name": "rBHu8l6UcKyAfzDsAAAPN5YrVxw870.jpg",
				 "url":  "http://47.93.148.192:8080/xxx.jpg"
			}
		新上传的图片文件对象的结构
			{
				name: "e814ec6fd86c5a8c.jpg"
				response: {
					data: "http://182.92.128.115:8080/group1/xxx.jpg"
				}
				url: "blob:http://localhost:9529/a5199d82-0811-442d-9ec2-dafae83d9ed9"
			}
		提交保存/更新SPU请求的图片对象的结构(目标):
			 {
			    "imgName": "下载 (1).jpg",
			    "imgUrl": "http://47.93.148.192:8080/xxx.jpg"
			 }
      */
    spuInfo.spuImageList = spuInfo.spuImageList.map((item) => ({
      imgName: item.name as string,
      imgUrl: item.response ? item.response.data : item.imgUrl,
    }));

    /* 
    处理: 删除没有属性值的属性对象, 删除属性对象中的edit和valueName属性
    对spuInfo.spuSaleAttrList进行过滤(spuSaleAttrValueList是空数组) 
    */
    spuInfo.spuSaleAttrList = spuInfo.spuSaleAttrList.filter((item) => {
      if (item.spuSaleAttrValueList.length > 0) {
        delete item.isShowEdit;
        return true;
      }
      return false;
    });

    // 如果一个spu的销售属性都没有了, 不发请求并提示
    if (spuInfo.spuSaleAttrList.length === 0) {
      ElMessage.warning("必须SPU销售属性!");
      return;
    }

    // 添加三级分类ID属性
    spuInfo.category3Id = categoryStore.getCategory3Id;

    // 发保存/更新spuInfo的请求
    await addOrUpdateSpuApi(spuInfo);

    // 请求成功后, 做后续的响应处理
    ElMessage.success("保存成功!");
    // 重置/清除数据
    emits("setShowStatus", ShowStatus.SPU_LIST);
  };

  /**
   * 添加spu销售属性
   */
  const addSpuSaleAttr = () => {
    const [id, name] = saleAttrIdName.value.split(":");
    /* 
    向spuInfo.spuSaleAttrList中添加一个属性对象:
      {
          "baseSaleAttrId": "1", // 销售属性id
          "saleAttrName": "选择颜色",  // 销售属性名
          "spuSaleAttrValueList": []
        }
    */
    spuInfo.spuSaleAttrList.push({
      baseSaleAttrId: +id, // 销售属性id
      saleAttrName: name, // 销售属性名
      spuSaleAttrValueList: [],
    });
    // 清除收集的数据
    saleAttrIdName.value = "";
  };

  /**
   * 变为查看模式
   * @param saleAttr
   */
  const toView = (saleAttr: SpuSaleAttrModel) => {
    if (saleAttrValueName.value) {
      // 添加
      saleAttr.spuSaleAttrValueList.push({
        baseSaleAttrId: saleAttr.baseSaleAttrId,
        saleAttrValueName: saleAttrValueName.value,
      });
      // 清空
      saleAttrValueName.value = "";
    }
    // 变成显示模式
    saleAttr.isShowEdit = false;
  };

  /**
   * 变为编辑模式
   * @param row
   * @param index
   *
   */
  const toEdit = (row: SpuSaleAttrModel, index: number) => {
    // 显示Input
    row.isShowEdit = true;
    // 在input自动获取焦点
    nextTick(() => {
      inputsRef.value[index].focus();
    });
  };
</script>

<style scoped></style>
